﻿Namespace Misc
	Public Class Names
		Private Shared shorts As New Dictionary(Of String, String)
		Private Shared noCaps As New Dictionary(Of String, String)
		Shared Sub New()
			shorts.Add("id", "#")
			shorts.Add("rate", "$")
			shorts.Add("current", "Cur")
			shorts.Add("customer", "Cust")
			shorts.Add("number", "#")
			'shorts.Add("number", "#")
			shorts.Add("percent", "%")
			shorts.Add("percentage", "%")
			shorts.Add("and", "&")
			shorts.Add("dollar", "$")
			shorts.Add("amount", "$")
			shorts.Add("$ $", "$")
			shorts.Add("times", "x's")
			shorts.Add("one", "1")
			shorts.Add("first", "1st")
			'shorts.Add("second", "2nd")
			shorts.Add("two", "2")
			shorts.Add("third", "3rd")
			shorts.Add("three", "3")
			shorts.Add("four", "4")
			shorts.Add("fifth", "5th")
			shorts.Add("five", "5")
			shorts.Add("six", "6")
			shorts.Add("seven", "7")
			shorts.Add("eighth", "8th")
			shorts.Add("eight", "8")
			shorts.Add("ninth", "9th")
			shorts.Add("nine", "9")
			shorts.Add("ten", "10")
			shorts.Add("eleven", "11")
			shorts.Add("twelve", "12")
			shorts.Add("thirteen", "13")
			shorts.Add("fourteen", "14")
			shorts.Add("fifteen", "15")
			shorts.Add("sixteen", "16")
			shorts.Add("seventeen", "17")
			shorts.Add("eightteen", "18")
			shorts.Add("nineteen", "19")
			shorts.Add("twentieth", "20th")
			shorts.Add("twenty", "20")
			shorts.Add("thirtieth", "30th")
			shorts.Add("thirty", "30")
			shorts.Add("fourtieth", "40th")
			shorts.Add("fourty", "40")
			shorts.Add("fiftieth", "50th")
			shorts.Add("fifty", "50")
			shorts.Add("sixtieth", "60th")
			shorts.Add("sixty", "60")
			shorts.Add("eightieth", "80th")
			shorts.Add("eighty", "80")
			shorts.Add("nintieth", "90th")
			shorts.Add("ninty", "90")
			'shorts.Add(" hundred", "00")
			'shorts.Add(" thousand", ",000")
			shorts.Add("january", "Jan")
			shorts.Add("february", "Feb")
			shorts.Add("march", "Mar")
			shorts.Add("april", "Apr")
			shorts.Add("may", "May")
			shorts.Add("june", "Jun")
			shorts.Add("july", "Jul")
			shorts.Add("august", "Aug")
			shorts.Add("september", "Sep")
			shorts.Add("october", "Oct")
			shorts.Add("november", "Nov")
			shorts.Add("december", "Dec")
			shorts.Add("county", "Co")
			shorts.Add("department", "Dept")
			shorts.Add("division", "Div")
			shorts.Add("doctor", "Dr")
			shorts.Add("drive", "Dr")
			shorts.Add("west", "W")
			shorts.Add("east", "E")
			shorts.Add("north", "N")
			shorts.Add("south", "S")
			shorts.Add("hour", "Hr")
			shorts.Add("hours", "Hrs")
			shorts.Add("minutes", "Min")
			shorts.Add("seconds", "Sec")
			shorts.Add("minute", "Min")
			'shorts.Add("second", "Sec")
			shorts.Add("junior", "Jr")
			shorts.Add("senior", "Sr")
			shorts.Add("kilogram", "Kg")
			shorts.Add("kilograms", "Kg")
			shorts.Add("kilometers", "Km")
			shorts.Add("kilometer", "Km")
			shorts.Add("longitude", "Long")
			shorts.Add("latitude", "Lat")
			shorts.Add("mile", "Mi")
			shorts.Add("miles", "Mi")
			shorts.Add("northeast", "Ne")
			shorts.Add("southeast", "Se")
			shorts.Add("northwest", "Nw")
			shorts.Add("southwest", "Ww")
			shorts.Add("ounce", "Oz")
			shorts.Add("ounces", "Pz")
			shorts.Add("population", "Pop")
			shorts.Add("revised", "Rev")
			shorts.Add("square", "Sq")
			shorts.Add("feet", "Ft")
			shorts.Add("volume", "Vol")
			shorts.Add("volumes", "Vols")
			shorts.Add("versus", "Vs")
			shorts.Add("abbreviation", "Abbr")
			shorts.Add("abbreviations", "Abbr")
			shorts.Add("abbreviated", "Abbr")
			shorts.Add("altitude", "Alt")
			shorts.Add("avenue", "Ave")
			shorts.Add("road", "Rd")
			shorts.Add("street", "St")
			shorts.Add("circle", "Cir")
			shorts.Add("boulevard", "blvd")
			shorts.Add("government", "Gov")
			'shorts.Add("key business unit", "KBU")
			'shorts.Add("key business executive", "KBE")
			'shorts.Add("information technology", "IT")
			shorts.Add("date", "Dt")
			shorts.Add("through", "-")
			shorts.Add("column", "Col")
			shorts.Add("columns", "Cols")
			shorts.Add("source", "Src")
			shorts.Add("account", "Acct")
			shorts.Add("address", "Addr")
			shorts.Add("balance", "Bal")
			shorts.Add("year", "Yr")
			shorts.Add("description", "Desc")
			shorts.Add("termination", "Term")
			shorts.Add("quarter", "Qtr")
			shorts.Add("discount", "Disc")
			shorts.Add("message", "Msg")
			shorts.Add("reference", "ref")
			shorts.Add("distribution", "Dist")
			shorts.Add("employee", "Emp")

			noCaps.Add("A", "a")
			noCaps.Add("About", "about")
			noCaps.Add("Above", "above")
			noCaps.Add("Across", "across")
			noCaps.Add("After", "after")
			noCaps.Add("Against", "against")
			noCaps.Add("Along", "along")
			noCaps.Add("Among", "among")
			noCaps.Add("And", "and")
			noCaps.Add("Around", "around")
			noCaps.Add("At", "at")
			noCaps.Add("Before", "before")
			noCaps.Add("Behind", "behind")
			noCaps.Add("Below", "below")
			noCaps.Add("Beneath", "beneath")
			noCaps.Add("Beside", "beside")
			noCaps.Add("Between", "between")
			noCaps.Add("Beyond", "beyond")
			noCaps.Add("But", "but")
			noCaps.Add("By", "by")
			noCaps.Add("Despite", "despite")
			noCaps.Add("Down", "down")
			noCaps.Add("During", "during")
			noCaps.Add("Except", "except")
			noCaps.Add("For", "for")
			noCaps.Add("From", "from")
			noCaps.Add("In", "in")
			noCaps.Add("Inside", "inside")
			noCaps.Add("Into", "into")
			noCaps.Add("Is", "is")
			noCaps.Add("It", "it")
			noCaps.Add("Like", "like")
			noCaps.Add("Near", "near")
			noCaps.Add("Nor", "nor")
			noCaps.Add("Of", "of")
			noCaps.Add("Off", "off")
			noCaps.Add("On", "on")
			noCaps.Add("Onto", "onto")
			noCaps.Add("Or", "or")
			noCaps.Add("Out", "out")
			noCaps.Add("Outside", "outside")
			noCaps.Add("Over", "over")
			noCaps.Add("Past", "past")
			noCaps.Add("Since", "since")
			noCaps.Add("So", "so")
			noCaps.Add("The", "the")
			noCaps.Add("This", "this")
			noCaps.Add("Through", "through")
			noCaps.Add("Throughout", "throughout")
			noCaps.Add("Till", "till")
			noCaps.Add("To", "to")
			noCaps.Add("Toward", "toward")
			noCaps.Add("Under", "under")
			noCaps.Add("Underneath", "underneath")
			noCaps.Add("Until", "until")
			noCaps.Add("Up", "up")
			noCaps.Add("Upon", "upon")
			noCaps.Add("With", "with")
			noCaps.Add("Within", "within")
			noCaps.Add("Without", "without")
			noCaps.Add("Yet", "yet")
		End Sub
		Public Shared Function Title(ByVal value As String) As String
			value = Replace(value, "_", " ")
			For i = Len(value) - 1 To 2 Step -1
				If Mid(value, i, 1) = UCase(Mid(value, i, 1)) AndAlso Mid(value, i + 1, 1) = LCase(Mid(value, i + 1, 1)) AndAlso Mid(value, i + 1, 1) <> " " Then
					value = value.Insert(i - 1, " ")
				End If
				If Mid(value, i, 1) = UCase(Mid(value, i, 1)) AndAlso Mid(value, i - 1, 1) = LCase(Mid(value, i - 1, 1)) AndAlso Mid(value, i - 1, 1) <> " " Then
					value = value.Insert(i - 1, " ")
				End If
				If Mid(value, i, 1) <> " " AndAlso Mid(value, i - 1, 1) = " " Then
					Mid(value, i, 1) = UCase(Mid(value, i, 1))
				End If
			Next
			value = Replace(value, "  ", " ")
			Dim words() = Split(value, " ")
			For i As Integer = 0 To words.Length - 1
				Dim word = words(i)
				If noCaps.ContainsKey(word) Then
					words(i) = noCaps(word)
				End If
			Next i
			value = Join(words, " ")
			Mid(value, 1, 1) = UCase(Mid(value, 1, 1))
			Return FixCaps(value)
		End Function
		Public Shared Function Singular(ByVal value As String) As String
			value = Title(value)
			' Get last word
			Dim pos = InStrRev(value, " ")
			If pos = 0 Then
				value = ToSingular(value)
			Else
				value = Mid(value, 1, pos) + ToSingular(Mid(value, pos + 1))
			End If
			Return FixCaps(value)
		End Function
		Public Shared Function Shorten(ByVal value As String) As String
			value = Title(value)

			If Microsoft.VisualBasic.Right(value, 3) = " Id" Then
				value = Microsoft.VisualBasic.Left(value, Len(value) - 3)
			End If
			If Microsoft.VisualBasic.Left(LCase(value), 3) = "is " Then
				value = Mid(value, 4) + "?"
			End If
			Dim words() = Split(value, " ")
			For i As Integer = 0 To words.Length - 1
				Dim key = LCase(words(i))
				If shorts.ContainsKey(key) Then
					words(i) = shorts(key)
				End If
			Next i
			value = Join(words, " ")
			value = ReplaceWord(value, "key business unit", "KBU")
			value = ReplaceWord(value, "key business executive", "KBE")
			value = ReplaceWord(value, "information technology", "IT")
			value = ReplaceWord(value, " hundred", "00")
			value = ReplaceWord(value, " thousand", ",000")

			Return value
		End Function
		Public Shared Function Prompt(ByVal value As String) As String
			value = Title(value)
			For i = 2 To Len(value)
				If Mid(value, i, 1) = UCase(Mid(value, i, 1)) And Mid(value, i - 1, 1) = " " And Mid(value, i + 1, 1) = LCase(Mid(value, i + 1, 1)) Then
					Mid(value, i, 1) = LCase(Mid(value, i, 1))
				End If
			Next
			Return value
		End Function

		Private Shared Function ToSingular(ByVal word As String) As String
			If LCase(word) = "barracks" Then Return FixCase("barracks", word)
			If LCase(word) = "crossroads" Then Return FixCase("crossroads", word)
			If LCase(word) = "dice" Then Return FixCase("die", word)
			If LCase(word) = "gallows" Then Return FixCase("gallows", word)
			If LCase(word) = "headquarters" Then Return FixCase("headquarters", word)
			If LCase(word) = "means" Then Return FixCase("means", word)
			If LCase(word) = "series" Then Return FixCase("series", word)
			If LCase(word) = "species" Then Return FixCase("species", word)
			If LCase(word) = "algae" Then Return FixCase("alga", word)
			If LCase(word) = "amoebae" Then Return FixCase("amoeba", word)
			If LCase(word) = "amoebas" Then Return FixCase("amoeba", word)
			If LCase(word) = "antennae" Then Return FixCase("antenna", word)
			If LCase(word) = "antennas" Then Return FixCase("antenna", word)
			If LCase(word) = "formulae" Then Return FixCase("formula", word)
			If LCase(word) = "formulas" Then Return FixCase("formula", word)
			If LCase(word) = "larvae" Then Return FixCase("larva", word)
			If LCase(word) = "nebulae" Then Return FixCase("nebula", word)
			If LCase(word) = "nebulas" Then Return FixCase("nebula", word)
			If LCase(word) = "vertebrae" Then Return FixCase("vertebra", word)
			If LCase(word) = "corpora" Then Return FixCase("corpus", word)
			If LCase(word) = "genera" Then Return FixCase("genus", word)
			If LCase(word) = "alumni" Then Return FixCase("alumnus", word)
			If LCase(word) = "bacilli" Then Return FixCase("bacillus", word)
			If LCase(word) = "cacti" Then Return FixCase("cactus", word)
			If LCase(word) = "cactuses" Then Return FixCase("cactus", word)
			If LCase(word) = "foci" Then Return FixCase("focus", word)
			If LCase(word) = "fungi" Then Return FixCase("fungus", word)
			If LCase(word) = "funguses" Then Return FixCase("fungus", word)
			If LCase(word) = "nuclei" Then Return FixCase("nucleus", word)
			If LCase(word) = "octopi" Then Return FixCase("octopus", word)
			If LCase(word) = "octopuses" Then Return FixCase("octopus", word)
			If LCase(word) = "radii" Then Return FixCase("radius", word)
			If LCase(word) = "stimuli" Then Return FixCase("stimulus", word)
			If LCase(word) = "syllabi" Then Return FixCase("syllabus", word)
			If LCase(word) = "syllabuses" Then Return FixCase("syllabus", word)
			If LCase(word) = "termini" Then Return FixCase("terminus", word)
			If LCase(word) = "addenda" Then Return FixCase("addendum", word)
			If LCase(word) = "bacteria" Then Return FixCase("bacterium", word)
			If LCase(word) = "curricula" Then Return FixCase("curriculum", word)
			If LCase(word) = "curriculums" Then Return FixCase("curriculum", word)
			If LCase(word) = "data" Then Return FixCase("datum", word)
			If LCase(word) = "errata" Then Return FixCase("erratum", word)
			If LCase(word) = "media" Then Return FixCase("medium", word)
			If LCase(word) = "memoranda" Then Return FixCase("memorandum", word)
			If LCase(word) = "memorandums" Then Return FixCase("memorandum", word)
			If LCase(word) = "ova" Then Return FixCase("ovum", word)
			If LCase(word) = "strata" Then Return FixCase("stratum", word)
			If LCase(word) = "symposia" Then Return FixCase("symposium", word)
			If LCase(word) = "symposiums" Then Return FixCase("symposium", word)
			If LCase(word) = "apices" Then Return FixCase("apex", word)
			If LCase(word) = "apexes" Then Return FixCase("apex", word)
			If LCase(word) = "appendices" Then Return FixCase("appendix", word)
			If LCase(word) = "appendixes" Then Return FixCase("appendix", word)
			If LCase(word) = "cervices" Then Return FixCase("cervix", word)
			If LCase(word) = "cervixes" Then Return FixCase("cervix", word)
			If LCase(word) = "indices" Then Return FixCase("index", word)
			If LCase(word) = "indexes" Then Return FixCase("index", word)
			If LCase(word) = "matrices" Then Return FixCase("matrix", word)
			If LCase(word) = "matrixes" Then Return FixCase("matrix", word)
			If LCase(word) = "vortices" Then Return FixCase("vortex", word)
			If LCase(word) = "analyses" Then Return FixCase("analysis", word)
			If LCase(word) = "axes" Then Return FixCase("axis", word)
			If LCase(word) = "bases" Then Return FixCase("basis", word)
			If LCase(word) = "crises" Then Return FixCase("crisis", word)
			If LCase(word) = "diagnoses" Then Return FixCase("diagnosis", word)
			If LCase(word) = "emphases" Then Return FixCase("emphasis", word)
			If LCase(word) = "hypotheses" Then Return FixCase("hypothesis", word)
			If LCase(word) = "neuroses" Then Return FixCase("neurosis", word)
			If LCase(word) = "oases" Then Return FixCase("oasis", word)
			If LCase(word) = "parentheses" Then Return FixCase("parenthesis", word)
			If LCase(word) = "synopses" Then Return FixCase("synopsis", word)
			If LCase(word) = "theses" Then Return FixCase("thesis", word)
			If LCase(word) = "criteria" Then Return FixCase("criterion", word)
			If LCase(word) = "phenomena" Then Return FixCase("phenomenon", word)
			If LCase(word) = "automata" Then Return FixCase("automaton", word)
			If LCase(word) = "libretti" Then Return FixCase("libretto", word)
			If LCase(word) = "tempi" Then Return FixCase("tempo", word)
			If LCase(word) = "virtuosi" Then Return FixCase("virtuoso", word)
			If LCase(word) = "cherubim" Then Return FixCase("cherub", word)
			If LCase(word) = "seraphim" Then Return FixCase("seraph", word)
			If LCase(word) = "schemata" Then Return FixCase("schema", word)
			If LCase(word) = "pies" Then Return FixCase("pie", word)
			If LCase(word) = "addresses" Then Return FixCase("address", word)
			If LCase(word) = "description" Then Return FixCase("desc", word)

			If Microsoft.VisualBasic.Right(word, 3) = "ies" Then
				Return Microsoft.VisualBasic.Left(word, Len(word) - 3) + "y"
			End If
			If Microsoft.VisualBasic.Right(word, 2) = "'s" Then
				Return word
			End If
			If Microsoft.VisualBasic.Right(word, 1) = "s" Then
				word = Microsoft.VisualBasic.Left(word, Len(word) - 1)
				If Microsoft.VisualBasic.Right(word, 4) = "tche" Then
					Return Microsoft.VisualBasic.Left(word, Len(word) - 1)
				End If
				If Microsoft.VisualBasic.Right(word, 2) = "xe" Then
					Return Microsoft.VisualBasic.Left(word, Len(word) - 1)
				End If
			End If
			Return word
		End Function
		Private Shared Function FixCase(ByVal fixWord As String, ByVal sample As String) As String
			If Mid(sample, 1, 1) = UCase(Mid(sample, 1, 1)) Then
				Mid(fixWord, 1, 1) = UCase(Mid(fixWord, 1, 1))
			End If
			Return fixWord
		End Function
		Private Shared Function ReplaceWord(ByVal value As String, ByVal word As String, ByVal replacement As String) As String
			value = Replace(value, " " + word + " ", " " + replacement + " ", 1, -1, CompareMethod.Text)
			If Microsoft.VisualBasic.Left(word, 1) = " " Then
				value = Replace(value, word, replacement, 1, -1, CompareMethod.Text)
			End If
			If LCase(Microsoft.VisualBasic.Left(value, Len(word) + 1)) = word + " " Then
				value = replacement + Mid(value, Len(word) + 1)
			End If
			If LCase(Microsoft.VisualBasic.Right(value, Len(word) + 1)) = " " + word Then
				value = Microsoft.VisualBasic.Left(value, Len(value) - Len(word)) + replacement
			End If
			If LCase(value) = word Then
				value = replacement
			End If
			Return value
		End Function
		Private Shared Function FixCaps(ByVal value As String) As String
			value = Replace(value, " am ", " am ", 1, -1, CompareMethod.Text)
			value = Replace(value, " pm ", " pm ", 1, -1, CompareMethod.Text)
			Return value
		End Function
	End Class
End Namespace
